﻿// ===============================================================================
//  Copyright © ymind.net. All rights reserved .
//  官方网站：http://ymind.net/
//  版权所有：彦铭工作室 老陈出品
// ===============================================================================

using System;
using System.Configuration;
using System.Xml;
using Lcsoft.UrlRewriter.Actions;
using Lcsoft.UrlRewriter.Configuration;
using Lcsoft.UrlRewriter.Utilities;

namespace Lcsoft.UrlRewriter.Parsers
{
	/// <summary>
	/// 解析 &lt;rewrite&gt; 标记。
	/// </summary>
	public sealed class RewriteActionParser : RewriteActionParserBase
	{
		/// <summary>
		/// 获取动作名。
		/// </summary>
		public override string Name
		{
			get { return Constants.ElementRewrite; }
		}

		/// <summary>
		/// 获取一个值，该值指示当前动作是否允许嵌套动作。
		/// </summary>
		public override bool AllowsNestedActions
		{
			get { return false; }
		}

		/// <summary>
		/// 获取一个值，该值指示当前动作是否允许包含 Attribute 属性。
		/// </summary>
		public override bool AllowsAttributes
		{
			get { return true; }
		}

		/// <summary>
		/// 执行地址重写动作解析。
		/// </summary>
		/// <param name="node">包含要解析的动作信息的。</param>
		/// <param name="config">地址重写配置信息。</param>
		/// <returns>返回地址重写动作的实例。</returns>
		public override IRewriteAction Parse(XmlNode node, RewriterConfiguration config)
		{
			if (node == null) throw new ArgumentNullException("node");
			if (node.Attributes == null) throw new ArgumentOutOfRangeException("node");

			if (config == null) throw new ArgumentNullException("config");

			var toNode = node.Attributes[Constants.AttrTo];

			if (toNode.Value == null) throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.AttributeRequired, Constants.AttrTo), node);

			var processingNode = node.Attributes[Constants.AttrProcessing];
			var processing = RewriteProcessing.ContinueProcessing;

			if (processingNode != null)
			{
				switch (processingNode.Value)
				{
					case Constants.AttrValueRestart:
						processing = RewriteProcessing.RestartProcessing;

						break;
					case Constants.AttrValueStop:
						processing = RewriteProcessing.StopProcessing;

						break;
					default:
						if (processingNode.Value != Constants.AttrValueContinue) throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.ValueOfProcessingAttribute, processingNode.Value, Constants.AttrValueContinue, Constants.AttrValueRestart, Constants.AttrValueStop), node);

						break;
				}
			}

			var action = new RewriteAction(toNode.Value, processing);

			this.ParseConditions(node, action.Conditions, false, config);

			return action;
		}
	}
}
